/*------------------------------------------------------------------------------*\
**   Copyright 2008 Jonhnny Weslley                                             **
**                                                                              **
**   Licensed under the Apache License, Version 2.0 (the "License");            **
**   you may not use this file except in compliance with the License.           **
**   You may obtain a copy of the License at                                    **
**                                                                              **
**       http://www.apache.org/licenses/LICENSE-2.0                             **
**                                                                              **
**   Unless required by applicable law or agreed to in writing, software        **
**   distributed under the License is distributed on an "AS IS" BASIS,          **
**   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   **
**   See the License for the specific language governing permissions and        **
**   limitations under the License.                                             **
\*------------------------------------------------------------------------------*/

package shibernate

trait CriteriaLanguage {

  implicit def str2Property(property: String) = Property(property)
  implicit def value2Parameter(sbv: BinaryValue) = sbv.param

  def not(param: CriterionParameter) = BinaryValue(Not(param))

}

case class Property(val name: String) {

  def neq(value: Any) = BinaryValue(NotEquals(name, value))

  def eql(value: Any) = BinaryValue(Equals(name, value))

  def le(value: Any) = BinaryValue(LowerEquals(name, value))

  def lt(value: Any) = BinaryValue(LowerThan(name, value))

  def ge(value: Any) = BinaryValue(GreaterEquals(name, value))

  def gt(value: Any) = BinaryValue(GreaterThan(name, value))

  def like(value: Any) = BinaryValue(Like(name, value))

  def between[A](value: (A, A)) = BinaryValue(Between(name, value._1, value._2))

  def asc = UnaryValue(OrderBy(name, true))

  def desc = UnaryValue(OrderBy(name, false))

}

abstract class Value {
  val param: Parameter
}

case class UnaryValue(param: Parameter) extends Value

case class BinaryValue(param: CriterionParameter) extends Value {

  def and(other: CriterionParameter) = BinaryValue(And(param, other))
  def &(other: CriterionParameter) = BinaryValue(And(param, other))

  def or(other: CriterionParameter) = BinaryValue(Or(param, other))
  def |(other: CriterionParameter) = BinaryValue(Or(param, other))

}
